import Http from 'axios'

const createOfdConvertTaskUrl = `/xsajbl-service/api/caseDocPrinting/convertToOfd`
const createPdfConvertTaskUrl = `/xsajbl-service/api/caseDocPrinting/convertToPdf`
const queryConvertTaskUrl = `/xsajbl-service/api/caseDocPrinting/queryProcessState`
const saveConvertedFileUrl = `/xsajbl-service/api/caseDocPrinting/saveOfdByTicket`

function ensureFormat(format) {
  switch (format) {
    case 'doc':
    case 'docx':
    case 'wps':
    case 'xlsx':
    case 'xls':
    case 'pdf':
    case 'png':
    case 'jpeg':
    case 'jpg':
    case 'bmp':
      break
    default:
      console.log('目前支持转为版式文件的源文件格式有: doc/docx/wps/xls/xlsx/pdf/png/jpeg/jpg/bmp')
      throw Error(`不受格式转换支持的格式: ${format}`)
  }
}

function isSuwellLocalPluginUsable() {
  const version = navigator.plugins['Suwell Reader Plugin']
  return typeof version !== 'undefined'
}

async function pollingUntilFinish(ticket, queryServerUrl, maxQueryTimes) {
  let times = 1
  maxQueryTimes = maxQueryTimes || 15

  while (true) {
    // 每隔1.5秒查询一次
    await sleep(1500)

    const result = await Http.post(queryServerUrl, {
      ticket: ticket,
    })

    if (!result) {
      console.error(`查询文档转换进度失败, 1.5秒后继续重试查询, ticket: ${ticket}`)
    }
    if (!result.success) {
      console.error(`查询文档转换进度失败, 1.5秒后继续重试查询, ticket: ${ticket}`, result)
    }

    const state = result.data

    if (state.startsWith('http')) {
      return
    } else {
      console.log(`转版中, 当前状态: ${state}, ticket: ${ticket}`)

      if (times++ >= maxQueryTimes) {
        throw Error(
          `文件未在${
            1.5 * maxQueryTimes
          }秒内完成转版, 取消等待. ticket: ${ticket}, state: ${state}`,
        )
      }
    }
  }
}

async function askServerDownloadFile(
  targetDir,
  targetName,
  overrideOnExists,
  ticket,
  saveServerUrl,
  format,
  wsslbh,
  sfyy,
) {
  const result = await Http.post(saveServerUrl, {
    targetDir: targetDir,
    targetName: targetName,
    overrideOnExists: overrideOnExists,
    ticket: ticket,
    wjkzm: format.toLowerCase(),
    wsslbh: wsslbh,
    // 打开方式：2 表示转版成功
    dkfs: 2,
    sfyy: sfyy,
  })

  if (!result) {
    throw Error(`请求服务器保存转版文件失败`)
  }
  if (!result.success) {
    console.log(result)
    throw Error(`请求服务器保存转版文件失败: ${result.message}`)
  }

  return result
}

async function doConvert({
  serverUrl,
  sourceDir,
  sourceName,
  targetDir,
  targetName,
  format,
  overrideOnExists,
  queryServerUrl,
  saveServerUrl,
  wsslbh,
  targetFormat,
  maxQueryTimes,
  sfyy,
  createExtend,
}) {
  ensureFormat(format)

  const result = await Http.post(serverUrl, {
    sourceDir: sourceDir,
    sourceName: sourceName,
    format: format,
    createExtend: createExtend,
  })

  if (!result) {
    throw Error(`请求文档转换失败`)
  }
  if (!result.success) {
    console.log(result)
    throw Error(`请求文档转换失败: ${result.message}`)
  }

  const ticket = result.data
  console.log(`转版任务ticket: ${ticket}`)

  await pollingUntilFinish(ticket, queryServerUrl, maxQueryTimes)

  return askServerDownloadFile(
    targetDir,
    targetName,
    overrideOnExists,
    ticket,
    saveServerUrl,
    targetFormat,
    wsslbh,
    sfyy,
  )
}

const fileConverter = {
  /**
   * 将文档转换为版式文件
   * @param sourceDir 源文档在存储中的dir
   * @param sourceName 源文档在存储中的name
   * @param targetDir 转换完成后的版式文件在存储中存放的dir
   * @param targetName 转换完成后的版式文件在存储中存放的name
   * @param format 源文档的格式, 如: wps/doc/docx等
   * @param overrideOnExists 当转targetDir/targetName 对应的文件已存在时是否强制覆盖
   * @param convertServerUrl 创建转版任务的地址，默认请求刑事案件办理的接口
   * @param queryServerUrl 查询转版任务的地址，默认请求刑事案件办理的接口
   * @param saveServerUrl 请求下载转版后文件的地址，默认请求刑事案件办理的接口
   * @param wsslbh 文书实例编号
   * @param maxQueryTimes 查询转版进度最多尝试次数， 每次间隔1.5秒
   * @param sfyy 是否用印
   * @param createExtend 创建转版任务的扩展参数，业务层自行定义
   *
   * @throws 网络请求异常或者转换失败的时候会抛出异常
   */
  toOFD: async ({
    sourceDir,
    sourceName,
    targetDir,
    targetName,
    format,
    overrideOnExists,
    convertServerUrl,
    queryServerUrl,
    saveServerUrl,
    wsslbh,
    maxQueryTimes,
    sfyy,
    createExtend,
  }) => {
    return doConvert({
      serverUrl: convertServerUrl || createOfdConvertTaskUrl,
      sourceDir: sourceDir,
      sourceName: sourceName,
      targetDir: targetDir,
      targetName: targetName,
      format: format,
      overrideOnExists: overrideOnExists,
      queryServerUrl: queryServerUrl || queryConvertTaskUrl,
      saveServerUrl: saveServerUrl || saveConvertedFileUrl,
      wsslbh: wsslbh,
      targetFormat: 'ofd',
      maxQueryTimes: maxQueryTimes,
      sfyy: sfyy,
      createExtend: createExtend,
    })
  },
  /**
   * 将文档转换为版式文件
   * @param sourceDir 源文档在存储中的dir
   * @param sourceName 源文档在存储中的name
   * @param targetDir 转换完成后的版式文件在存储中存放的dir
   * @param targetName 转换完成后的版式文件在存储中存放的name
   * @param format 源文档的格式, 如: wps/doc/docx等
   * @param overrideOnExists 当转targetDir/targetName 对应的文件已存在时是否强制覆盖
   * @param convertServerUrl 创建转版任务的地址，默认请求刑事案件办理的接口
   * @param queryServerUrl 查询转版任务的地址，默认请求刑事案件办理的接口
   * @param saveServerUrl 请求下载转版后文件的地址，默认请求刑事案件办理的接口
   * @param wsslbh 文书实例编号
   * @param maxQueryTimes 查询转版进度最多尝试次数， 每次间隔1.5秒
   * @param sfyy 是否用印
   * @param createExtend 创建转版任务的扩展参数，业务层自行定义
   *
   * @throws 网络请求异常或者转换失败的时候会抛出异常
   */
  toPDF: async ({
    sourceDir,
    sourceName,
    targetDir,
    targetName,
    format,
    overrideOnExists,
    convertServerUrl,
    queryServerUrl,
    saveServerUrl,
    wsslbh,
    maxQueryTimes,
    sfyy,
    createExtend,
  }) => {
    return doConvert({
      serverUrl: convertServerUrl || createPdfConvertTaskUrl,
      sourceDir: sourceDir,
      sourceName: sourceName,
      targetDir: targetDir,
      targetName: targetName,
      format: format,
      overrideOnExists: overrideOnExists,
      queryServerUrl: queryServerUrl || queryConvertTaskUrl,
      saveServerUrl: saveServerUrl || saveConvertedFileUrl,
      wsslbh: wsslbh,
      targetFormat: 'pdf',
      maxQueryTimes: maxQueryTimes,
      sfyy: sfyy,
      createExtend: createExtend,
    })
  },
  createCloudOfdReader: ({ parentNode, fileDir, fileName, readerServer, fileUrl }) => {
    if (!parentNode) {
      throw Error('缺少parentNode参数, 必须提供该参数作为轻阅读插件的父节点')
    }

    console.log(`fileUrl: ${fileUrl}, fileDir: ${fileDir}, fileName: ${fileName}`)

    if (!fileUrl && !(fileDir && fileName)) {
      throw Error('必须提供fileUrl或fileDir + fileName 参数标识OFD文档的下载地址')
    }

    fileUrl =
      fileUrl ||
      `${window.BASEURL}/wjfw-service/file/get?dir=${encodeURIComponent(
        fileDir,
      )}%26name=${encodeURIComponent(fileName)}`

    const cloudReaderUrl = `${readerServer}/web-reader/reader?file=${fileUrl}`

    parentNode.innerHTML = ''

    const _ofd = document.createElement('iframe')
    _ofd.setAttribute('src', cloudReaderUrl)
    _ofd.setAttribute('height', '100%')
    _ofd.setAttribute('width', '100%')
    _ofd.setAttribute('style', 'border: 0;')

    parentNode.appendChild(_ofd)
  },
  createLocalOfdReader: ({
    parentNode,
    fileDir,
    fileName,
    readOnly,
    wrapIframe,
    fileUrl,
    sealId,
  }) => {
    if (!isSuwellLocalPluginUsable()) {
      throw Error('本地OFD插件不可用, 请确认已安装OFD客户端')
    }
    if (!parentNode) {
      throw Error('缺少parentNode参数, 必须提供该参数作为轻阅读插件的父节点')
    }
    if (!fileUrl && !(fileDir && fileName)) {
      throw Error('必须提供fileUrl或fileDir + fileName 参数标识OFD文档的下载地址')
    }
    // if (sealId) {
    //   console.log(`仅允许使用ID为 ${sealId} 的印章`)
    // }

    console.log(`fileUrl: ${fileUrl}, fileDir: ${fileDir}, fileName: ${fileName}`)

    // let iframeId = null
    // if (wrapIframe) {
    //   iframeId = uuid()
    //   parentNode.innerHTML = `<iframe id="${iframeId}" style="width: 100%;height:100%;margin: 0 !important;padding: 0 !important;border: 0 !important;"></iframe>`
    //   const iframe = parentNode.firstElementChild

    //   iframe.contentDocument.write(
    //     `<body style="margin: 0 !important;"> <div id="__inner_ofd_reader__"></div> </body>`
    //   )

    //   parentNode = iframe.contentWindow.document.getElementById(
    //     '__inner_ofd_reader__'
    //   )
    // } else {
    parentNode.innerHTML = ''
    // }

    fileUrl =
      fileUrl ||
      `${window.BASEURL}/wjfw-service/file/get?dir=${encodeURIComponent(
        fileDir,
      )}&name=${encodeURIComponent(fileName)}`

    console.log(`预览文件: ${fileUrl}`)

    const ocx = suwellOfdReader.ofdReaderInit(
      parentNode.id,
      '100%',
      '100%',
      // iframeId
    )

    ocx.openFile(fileUrl, !!readOnly)
    // ocx.setSealId(sealId)

    ocx.showPlugin = () => {
      parentNode.querySelector('embed').style.visibility = 'visible'
    }
    ocx.hidePlugin = () => {
      parentNode.querySelector('embed').style.visibility = 'hidden'
    }

    return ocx
  },
  printOpenedOfd: ({ instance, count }) => {
    if (!instance) {
      throw Error('缺少instance参数, 必须提供instance标识要保存的OFD文档实例')
    }

    // instance.performClick('f_print')
    instance.printOfdFile(count)
  },
  /**
   * name对应的组件：
   * f_open       打开
   * f_import     导入文件
   * f_export     导出文件
   * f_save       保存
   * f_saveas     另存为
   * f_print      打印
   * f_close      关闭
   * d_sealsign   盖章
   * d_verifysign 验章
   * w_menu       显示/隐藏菜单栏
   * w_tool       显示/隐藏工具栏
   * w_statusbar  显示/隐藏底部工具栏
   * w_navigator  显示/隐藏导航栏（文档结构图）
   */
  toggleComponent: ({ instance, name, enable }) => {
    instance.setCompositeVisible(name, enable)
  },
  // 该接口只能保存由 createLocalOfdReader 接口打开的OFD文档
  saveOpenedOfd: ({ instance, targetDir, targetName, overrideOnExists, saveUrl }) => {
    if (!instance) {
      throw Error('缺少instance参数, 必须提供instance标识要保存的OFD文档实例')
    }

    saveUrl =
      saveUrl ||
      `${window.BASEURL}/wjfw-service/file/save?dir=${decodeURIComponent(
        targetDir,
      )}&name=${decodeURIComponent(targetName)}&overrideOnExists=${overrideOnExists}`

    console.log(`保存OFD文档, 保存地址: ${saveUrl}`)

    return instance.saveFile(saveUrl)
  },
  /**
   * 设置打印弹出对话框的复选框组件的默认值
   * @name 请使用 instance.printOptions 属性里配置的参数项
   */
  setPrintOption: ({ instance, option, value }) => {
    if (!instance) {
      throw Error('缺少instance参数, 必须提供instance标识要保存的OFD文档实例')
    }

    instance.setPrintCompsiteChecked(option, value)
  },
  printOptions: {
    // true选中灰度打印，false代表取消选中
    gray: 'print_gray',
    // 设置打印的份数，非负整数
    count: 'copies',
  },
  showPrintSetting() {
    const div = document.createElement('div')

    div.id = `div${Date.now()}`
    div.style.width = '0'
    div.style.height = '0'
    document.querySelector('body').appendChild(div)

    const ocx = suwellOfdReader.ofdReaderInit(
      div.id,
      '0',
      '0',
      // iframeId
    )

    ocx.showPrintSetting()
  },
  batchPrint({ srcFiles, printNums }) {
    console.log(arguments)
    const div = document.createElement('div')

    div.id = `div${Date.now()}`
    div.style.width = '0'
    div.style.height = '0'
    document.querySelector('body').appendChild(div)

    const ocx = suwellOfdReader.ofdReaderInit(
      div.id,
      '0',
      '0',
      // iframeId
    )
    return ocx.batchPrint(srcFiles, printNums)
  },
  getSealCount(instance) {
    if (!instance) {
      throw Error('缺少instance参数, 必须提供instance标识要获取印章数量的OFD文档实例')
    }

    return instance.getSignaturesCount('seal')
  },
  /**
   * @param parentNodeId 父节点ID，父节点的内容会被清空
   * @param srcFileUrl 已用印的文件的下载地址
   * @param mbFileUrls 待批量用印的文件的url地址数组
   * @param saveFileUrls mbFileUrls对应文档用印完成后的保存地址数组，和mbFileUrls一一对应
   * @param instance 阅读器实例
   */
  batchSeal({ parentNodeId, srcFileUrl, mbFileUrls, saveFileUrls, instance }) {
    if (!parentNodeId) {
      throw Error('缺少parentNodeId参数, 必须提供该参数作为批量用印插件的父节点')
    }
    if (!instance) {
      throw Error('缺少instance参数, 必须提供instance标识要保存的OFD文档实例')
    }
    if (!mbFileUrls || mbFileUrls.length === 0) {
      throw Error('未传入待盖章文件地址数组')
    }
    if (!saveFileUrls) {
      throw Error('未传入文件盖章后的保存地址数组')
    }
    if (mbFileUrls.length !== saveFileUrls.length) {
      throw Error('待盖章文件地址数组和保存地址数组数量不匹配')
    }

    console.log(
      `批量用印, 源文件地址: ${srcFileUrl}, 模板文件地址: ${mbFileUrls}, 保存地址: ${saveFileUrls}`,
    )

    const result = instance.sealByBatch(srcFileUrl, mbFileUrls.join(';'), saveFileUrls.join(';'))

    // 数科阅读器的sealByBatch返回的是JSON字符串
    return JSON.parse(result)
  },
  /**
   * @param instance 阅读器实例
   */
  async autoSeal({ parentNodeId, wsInfoArray }) {
    if (!parentNodeId) {
      throw Error('缺少parentNodeId参数, 必须提供该参数作为自动用印插件的父节点')
    }
    if (!wsInfoArray || wsInfoArray.length === 0) {
      throw Error('未传入需自动用印文书信息')
    }
    if (!$nuxt.$appConfig.autoSealAssistServer) {
      throw Error(`数科阅读器的嵌入式自动用印功能需配置autoSealAssistServer`)
    }

    const parentNode = document.querySelector(`#${parentNodeId}`)
    parentNode.innerHTML = ''
    parentNode.style.visibility = 'hidden'

    const ocx = suwellOfdReader.ofdReaderInit(
      parentNodeId,
      '0',
      '0',
      // iframeId
    )

    const mbfwpz = {
      addr: $nuxt.$appConfig.autoSealAssistServer,
      headers: [],
    }
    if ($nuxt.$appConfig.gatewayHeaderName && $nuxt.$appConfig.gatewayToken) {
      mbfwpz.headers.push({
        name: $nuxt.$appConfig.gatewayHeaderName,
        value: $nuxt.$appConfig.gatewayToken,
      })
    }

    wsInfoArray.forEach((item) => {
      item.mbfwpz = mbfwpz
    })

    console.log(`自动用印. `, wsInfoArray)
    const result = await ocx.sealByAuto(JSON.stringify({ wsInfoArray: wsInfoArray }))

    // 数科阅读器的sealByBatch返回的是JSON字符串
    return JSON.parse(result)
  },
  async getPageCount(instance) {
    if (!instance) {
      throw Error('缺少instance参数, 必须提供instance标识要获取页面数量的OFD文档实例')
    }

    return instance.getPageCount()
  },
}

function sleep(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms))
}

export default fileConverter
